package com.baijiayun.liveuibase.toolbox.screenshare

import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import com.baijiayun.livecore.context.LPConstants
import com.baijiayun.livecore.context.LiveRoom
import com.baijiayun.livecore.utils.LPLogger
import com.baijiayun.livecore.utils.LPRxUtils
import com.baijiayun.livecore.wrapper.LPRecorder
import com.baijiayun.liveuibase.R
import com.baijiayun.liveuibase.utils.DisplayUtils
import com.baijiayun.liveuibase.utils.RxUtils
import com.baijiayun.liveuibase.utils.drawable.DrawableBuilder
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.bjy_base_view_floating.view.*
import kotlinx.android.synthetic.main.bjy_base_view_floating.view.screen_share_audio_iv
import kotlinx.android.synthetic.main.bjy_base_view_floating.view.screen_share_stop_iv
import java.util.concurrent.TimeUnit

/**
 * Created by pengwenjian on 2021/9/28
 * Describe:
 */
class ScreenShareHelper(private val activity: AppCompatActivity, private val liveRoom: LiveRoom) {
    companion object {
        const val TAG = "ScreenShareHelper"
        const val OVERLAY_PERMISSION_REQ_CODE = 66
        const val OVERLAY_PERMISSION_SHARE_REQ_CODE = 67
    }

    var screenShareListener: ScreenShareListener? = null
    private var isScreenSharing = false
    private var screenShareDialog: ScreenShareDialog? = null
    private var disposables: CompositeDisposable? = null
    private val floatingView by lazy {
        val floatingView =
            FloatingView(activity.applicationContext, R.layout.bjy_base_view_floating)
        floatingView.background = DrawableBuilder()
            .solidColor(ContextCompat.getColor(activity, R.color.base_half_black))
            .cornerRadius(DisplayUtils.dip2px(activity, 10f))
            .build()
        floatingView
    }

    init {
        disposables = CompositeDisposable()
        floatingView.screen_share_audio_iv.setImageDrawable(
            AppCompatResources.getDrawable(
                activity,
                R.drawable.bjy_base_sel_audio_state
            )
        )
        floatingView.screen_share_stop_iv.setOnClickListener {
            stopScreenCapture()
        }
        disposables?.add(RxUtils.clicks(floatingView.screen_share_audio_iv)
            .throttleFirst(500, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                if (floatingView.screen_share_audio_iv.isSelected) {
                    liveRoom.getRecorder<LPRecorder>().attachAudio()
                } else {
                    liveRoom.getRecorder<LPRecorder>().detachAudio()
                }
            })
        disposables?.add(liveRoom.getRecorder<LPRecorder>().observableOfScreenShareState
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                screenShareListener?.onScreenShareState(it)
                when (it) {
                    LPConstants.LPScreenShareState.START -> {
                        isScreenSharing = true
                        showScreenShareDialog()
                    }
                    LPConstants.LPScreenShareState.STOP, LPConstants.LPScreenShareState.ERROR -> {
                        isScreenSharing = false
                        if (floatingView.isShown) {
                            floatingView.dismiss()
                        }
                        stopScreenShareService()
                        screenShareDialog?.dismissAllowingStateLoss()
                    }
                    else -> {
                    }
                }
            })
        disposables?.add(liveRoom.getRecorder<LPRecorder>().observableOfMicOn
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                screenShareDialog?.updateScreenShareAudioState(it)
                updateScreenShareAudioState(it)
            })
    }

    private fun updateScreenShareAudioState(isAudioOn:Boolean) {
        if (!isScreenSharing) {
            return
        }
        floatingView.screen_share_audio_iv.isSelected = !isAudioOn
        floatingView.screen_share_audio_tv.text = if (!isAudioOn) {
            activity.getString(R.string.bjy_base_share_screen_audio_off)
        } else {
            activity.getString(R.string.bjy_base_share_screen_audio_on)
        }
    }

    fun onResume() {
        if (floatingView.isShown) {
            floatingView.dismiss()
        }
    }

    fun onStop() {
        if (isScreenSharing) {
            requestDrawOverLays()
        }
    }

    fun onDestroy() {
        isScreenSharing = false
        LPRxUtils.dispose(disposables)
        if (floatingView.isShown) {
            floatingView.dismiss()
        }
        stopScreenShareService()
        if (screenShareDialog?.isAdded == true) {
            screenShareDialog?.dismissAllowingStateLoss()
        }
    }

    fun startScreenCapture(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(activity)) {
            val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + activity.packageName)
            )
            activity.startActivityForResult(intent, OVERLAY_PERMISSION_SHARE_REQ_CODE)
        } else {
            return screenCapture()
        }
        return false
    }

    fun stopScreenCapture() {
        liveRoom.getRecorder<LPRecorder>().stopScreenCapture()
        stopScreenShareService()
        screenShareDialog?.dismissAllowingStateLoss()
        floatingView.dismiss()
    }

    private fun screenCapture(): Boolean {
        if (isScreenSharing) {
            LPLogger.e(TAG, "screen sharing")
            return false
        }
        startScreenShareService()
        val startScreenCapture = liveRoom.getRecorder<LPRecorder>().startScreenCapture(null)
        LPLogger.d(TAG, "startScreenCapture:$startScreenCapture")
        return startScreenCapture
    }

    /**
     *  Api29之后录屏需要开启前台服务
     */
    private fun startScreenShareService() {
        val intent = Intent(activity,ScreenShareService::class.java)
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
            activity.startForegroundService(intent)
        } else {
            activity.startService(intent)
        }
    }

    private fun stopScreenShareService() {
        activity.stopService(Intent(activity,ScreenShareService::class.java))
    }

    private fun showScreenShareDialog() {
        screenShareDialog = ScreenShareDialog()
        screenShareDialog?.screenShareListener = object : ScreenShareDialog.ScreenShareListener {
            override fun onScreenShareAudioOn() {
                liveRoom.getRecorder<LPRecorder>().attachAudio()
            }

            override fun onScreenShareAudioOff() {
                liveRoom.getRecorder<LPRecorder>().detachAudio()
            }

            override fun onScreenShareStop() {
                screenShareListener?.onScreenShareStop()
            }

            override fun onScreenShareBackToHome() {
                val intent = Intent()
                intent.action = Intent.ACTION_MAIN
                intent.addCategory(Intent.CATEGORY_HOME)
                activity.startActivity(intent)
            }
        }
        screenShareDialog?.isAudioOn = liveRoom.getRecorder<LPRecorder>().isAudioAttached
        screenShareDialog?.show(activity.supportFragmentManager, "screenShareDialog")
    }

    private fun requestDrawOverLays() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(activity)) {
            val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + activity.packageName)
            )
            activity.startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE)
        } else {
            showFloatingView()
        }
    }

    private fun showFloatingView() {
        if (!floatingView.isShown) {
            floatingView.show()
            updateScreenShareAudioState(liveRoom.getRecorder<LPRecorder>().isAudioAttached)
        }
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(activity)) {
                Toast.makeText(
                    activity,
                    activity.getString(R.string.bjy_base_screen_share_permission_toast),
                    Toast.LENGTH_SHORT
                ).show()
            } else {
                showFloatingView()
            }
        } else if (requestCode == OVERLAY_PERMISSION_SHARE_REQ_CODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(activity)) {
                Toast.makeText(
                    activity,
                    activity.getString(R.string.bjy_base_screen_share_permission_toast),
                    Toast.LENGTH_SHORT
                ).show()
            } else {
                screenCapture()
            }
        }
    }

    interface ScreenShareListener {
        fun onScreenShareState(state: LPConstants.LPScreenShareState)
        fun onScreenShareStop()
    }
}